﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;

using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Profiles;
using Styx.Pathing;						
using Styx.WoWInternals;				
using Styx.WoWInternals.WoWObjects;		
using Styx.Plugins;	

namespace rndbuddy
{
    static class settings
    {
        public static Version version = new Version(2, 8, 8);
        
        public static LocalPlayer Me = StyxWoW.Me;
		
		public static string conf_path = Path.Combine(Utilities.AssemblyDirectory, @"Settings\rndbuddy\");
        public static string conf_name = "rndbuddy." + Me.Name + ".conf";
        public static string api_key;
        public static string plugin_dir = Path.Combine(Utilities.AssemblyDirectory, @"Plugins\rndbuddy\");
        public static string app_data_dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\rndbuddy\";
        public static string[] remote_files = { "pbtemplate_0.xml", "pbtemplate_1.xml", "pbtemplate_530.xml", "pbtemplate_571.xml", "pbtemplate_870.xml", "rndbuddy_a.png", "donate.gif" };

        public static bool valid_key = false;
        public static bool autostart = true;
        public static bool fetch_new_assets_on_startup = true;
        public static bool overwrite_gb2_settings = true;
        public static bool enable_crowdsourcer = true;

        public static double crowdsourcer_collect_2d_distance = 250D;

        public static int http_timeout_sec = 15;
        public static int refresh_time = 25;
        public static int movement_watcher_samples = 60;
        public static int movement_watcher_min_distance = 50;
        public static int time_heartbeat = 25;
        public static int distance_to_end = 150;
        public static int unmount_node_distance = 20;
        public static int enable_refresh_on_end = 1;
        public static int enable_unmount_module = 1;
        public static int GuildLevelToJoin = 25;
        public static int dyn_reload_check = 15;
        public static int watch_expireTime = 60;
        public static int unmount_grace_period = 20;
        public static int max_stucks = 5;
        public static double max_idle_time = 45;

        public static bool followers_detection = false;
        public static int watch_range = 100;

        public static bool do_screenshots = true;
        public static int screenshot_interval_min = 10;
        public static bool screen_on_events = true;
        public static bool notify_on_events = true;

        public static bool jump = false;

        public static bool enable_opt_trackonly = false;

        public static bool use_mixed_mode_for_gathering = true;

        public static string wowpath = Styx.StyxWoW.Memory.Process.MainModule.FileName.Substring(0, Styx.StyxWoW.Memory.Process.MainModule.FileName.Length - 8);
        public static string scrpath = wowpath + @"\Screenshots\";

        public static DateTime timed_kill = System.DateTime.Now.AddYears(1);

        public static bool begin()
        {
            if (!System.IO.Directory.Exists(settings.app_data_dir))
            {
                rndbuddy.log("Creating rndbuddy working directory in " + settings.app_data_dir);
                System.IO.Directory.CreateDirectory(settings.app_data_dir);
            }
            
            if (!Directory.Exists(conf_path))
                Directory.CreateDirectory(conf_path);

            if (!File.Exists(conf_path + conf_name))
            {
				rndbuddy.log("Creating a new plain config");
                createPlainConfig();
            }
			
            parseConfig();
			
			if (server_pipe.validate_api_key())
            {
                valid_key = true;

                //run after validation tasks
                //parse remote config
                settings.parse_remote_settings();

                return true;
            }

			rndbuddy.logcrit("ERROR: No valid api key");
            //show registration dialog
            var frm = new form_signup();
            frm.ShowDialog();

            return true;
        }

        public static void parse_remote_settings()
        {
            string[] s = server_pipe.get_toon_settings();
            if (s[0] == "false")
            {
                rndbuddy.log("unable to get remote settings");
                rndbuddy.log("reason = " + s[1]);
                rndbuddy.log("falling back to defaults");
                return;
            }

            foreach (string t in s)
            {
                if (String.IsNullOrEmpty(t))
                    continue;

                string[] u = t.Split('=');
                int val_to_set;

                switch (u[0])
                {
                    case "default_server":
                        string new_server_url = "";
                        switch (u[1])
                        {
                            case "1":
                                new_server_url = "http://one.rndbuddy.com/";
                                break;
                            case "2":
                                new_server_url = "http://two.rndbuddy.com/";
                                break;
                            case "3":
                                new_server_url = "http://three.rndbuddy.com/";
                                break;
                            case "4":
                                new_server_url = "http://four.rndbuddy.com/";
                                break;
                            case "0":
                                break;
                            default:
                                throw new NotImplementedException("unexpected server override");
                        }
                        if (!String.IsNullOrEmpty(new_server_url))
                        {
                            rndbuddy.log("Using Server " + new_server_url);
                            server_pipe.server = new_server_url;
                            server_pipe.scr_server = new_server_url;
                        }
                        break;
                    
                    case "enable_refresh_on_end":
                        val_to_set = Convert.ToInt16(u[1]);
                        enable_refresh_on_end = val_to_set;
                        rndbuddy.logsilent("Setting Setting enable_refresh_on_end to " + val_to_set.ToString());
                        break;

                    case "enable_unmount_module":
                        val_to_set = Convert.ToInt16(u[1]);
                        enable_unmount_module = val_to_set;
                        rndbuddy.logsilent("Setting Setting enable_unmount_module to " + val_to_set.ToString());
                        break;

                    case "autostart":
                        settings.autostart = strint_to_bool(u[1]);
                        rndbuddy.logsilent("Setting Setting autostart to " + u[1]);
                        break;

                    case "fetch_new_assets_on_startup":
                        settings.fetch_new_assets_on_startup = strint_to_bool(u[1]);
                        rndbuddy.logsilent("Setting Setting Download of Assets to " + u[1]);
                        break;

                    case "screenshots":
                        settings.do_screenshots = strint_to_bool(u[1]);
                        rndbuddy.logsilent("Setting Setting Automatic Screenshot to " + u[1]);
                        break;

                    case "screenshot_interval":
                        settings.screenshot_interval_min = Convert.ToInt32(u[1]);
                        rndbuddy.logsilent("Setting Setting Screenshot interval to " + u[1] + " minutes!");
                        break;

                    case "screen_on_events":
                        settings.screen_on_events = strint_to_bool(u[1]);
                        rndbuddy.logsilent("Setting Setting Screenshot on Event to " + u[1]);
                        break;

                    case "notify_on_events":
                        settings.notify_on_events = strint_to_bool(u[1]);
                        rndbuddy.logsilent("Setting Setting Notification on Event to " + u[1]);
                        break;

                    case "jump":
                        settings.jump = strint_to_bool(u[1]);
                        rndbuddy.logsilent("Setting Setting Jump to " + u[1]);
                        break;

                    case "followers_detection":
                        settings.followers_detection = strint_to_bool(u[1]);
                        rndbuddy.logsilent("Setting Setting followers Detection to " + u[1]);
                        break;

                    case "overwrite_gb2":
                        settings.overwrite_gb2_settings = strint_to_bool(u[1]);
                        rndbuddy.logsilent("Setting Setting overwrite_gb2_settings to " + u[1]);
                        break;

                    case "max_exec_time":
                        settings.refresh_time = Convert.ToInt32(u[1]);
                        rndbuddy.logsilent("Setting Setting max profile time to " + u[1] + " minutes");
                        break;

                    case "enable_trackonly":
                        settings.enable_opt_trackonly = strint_to_bool(u[1]);
                        rndbuddy.logsilent("Setting Setting track other botbases to " + u[1]);
                        break;

                    case "pb_desired_zone":
                        ProfileHandler.pb_desired_zone = u[1];
                        rndbuddy.logsilent("Setting Setting Professionbuddy desired zone to " + u[1]);
                        break;

                    case "debug_crowdsourcer":
                        if (u[1] != "0")
                            break;
                        settings.enable_crowdsourcer = false;
                        rndbuddy.logcrit("CROWDSOURCER WAS REMOTELY DISABLED FOR DEBUGGING PURPOSE!");
                        break;
                }
            }
        }

        public static void createPlainConfig()
        {
            string[] lines = { "#rndbuddy config file", 
                               "#Backup this File to save your Settings", 
                               "api_key=0" 
                             };
            System.IO.File.WriteAllLines(conf_path + conf_name, lines);
        }

        public static void parseConfig()
        {
            string[] lines;
            try
            {
                lines = System.IO.File.ReadAllLines(conf_path + conf_name);
            }
            catch (System.IO.FileNotFoundException)
            {
                return;
            }
            foreach (string line in lines)
            {

                string ll;
                try { ll = line.Substring(0, 1); }
                catch (ArgumentOutOfRangeException)
                { ll = "#"; }

                if (ll != "#")
                {
                    string[] sta = line.Split('=');
                    switch (sta[0])
                    {
                        case "api_key":
                            api_key = sta[1];
                            break;
                    }
                }
            }
        }

        public static void storeConfig()
        {
            string[] lines = { "#rndbuddy config", 
                               "#", 
                               "api_key="+api_key 
                             };
            System.IO.File.WriteAllLines(conf_path + conf_name, lines);
        }

        public static bool am_i_up_to_date()
        {
            string localversion = settings.version.ToString();
            string[] v = localversion.Split('.');
            string lver = v[0] + v[1] + v[2];
            int lveri = Convert.ToInt32(lver);

            //get remote version
            string remver = server_pipe.server_version();
            int remveri = Convert.ToInt32(remver);

            if (lveri < remveri)
                return false;

            if (lveri > remveri)
                rndbuddy.log("Your version of rndbuddy is newer than the servers requires. This must not be bad ;)");

            return true;
        }

        public static bool strint_to_bool(string s)
        {
            if (s == "1")
                return true;
            return false;
        }

        public static void default_gb2_settings()
        {
            rndbuddy.log("Settings GB2 Settings to recommended Values");
            Bots.Gatherbuddy.GatherbuddySettings gbs = new Bots.Gatherbuddy.GatherbuddySettings();
            gbs.DiagnosticLogging = true;
            gbs.FaceNodes = false;
            gbs.MailToAlt = true;
            gbs.HearthAndExit = false;
            gbs.UseGuildVault = false;
            gbs.NoNinja = true;
            gbs.UseSpiritHealer = false;
            gbs.WaitRezSickness = false;
            gbs.HeightModifier = 0;
            gbs.Save();
        }

        public static void check_character_settings()
        {
            Styx.Helpers.CharacterSettings cs = new Styx.Helpers.CharacterSettings();
            if (String.IsNullOrEmpty(cs.MailRecipient))
                rndbuddy.logcrit("Warning: Please set a Mail recipient in order to enable mail support!");

            return;
        }

        public static int get_harvest_status(string what)
        {
            Bots.Gatherbuddy.GatherbuddySettings gbs = new Bots.Gatherbuddy.GatherbuddySettings();
            switch (what)
            {
                case "herb": return Convert.ToInt16(gbs.GatherHerbs);
                case "mine": return Convert.ToInt16(gbs.GatherMinerals);
                default: throw new NotImplementedException();
            }
        }

        public static void download_files_to_app_data()
        {
            rndbuddy.logsilent("Setting Downloading rndbuddy Files");
            WebClient webClient = new WebClient();
            foreach (string f in remote_files)
            {
                if (System.IO.File.Exists(settings.app_data_dir + f) && settings.fetch_new_assets_on_startup)
                {
                    webClient.DownloadFile("http://rndbuddy.googlecode.com/svn/trunk/" + f, settings.app_data_dir + f);
                }
                else if (!System.IO.File.Exists(settings.app_data_dir + f))
                {
                    rndbuddy.log("Downloading non-existent File " + f);
                    webClient.DownloadFile("http://rndbuddy.googlecode.com/svn/trunk/" + f, settings.app_data_dir + f);
                }
            }
        }
    }
}
